/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package FileStatistic;

/**
 *
 * <p>Package for get statistic of file. </p>
 * <p>1) StatisticToCSV(file) Get file name, Returns CSVFile with table: word, frequency, frequency in %;</p>
 * <p>2) ...;</p>
 * 
 * @author signal
 * @date 16.02.2011
 *
 * 
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

/**
 *
 * <p>Package for get statistic of file. </p>
 * <p>1) StatisticToCSV(file) Get file name, Returns CSVFile with table: word, frequency, frequency in %;</p>
 * <p>2) ...;</p>
 *
 */

public class FileStatistic 
{
	
	/**
	 * Function for create CSVFile with statistic about input <br/>
	 * 
	 * @param input the way to file; <br/>
	 * @return file with statistic; <br/>
	 */
	
	public static CSVFile StatisticToCSV(String input)
	{
		CSVFile returnCSVFile = new CSVFile();
		List<String[]> listToCSVF = new ArrayList();
		try {
			int countOfWords = 0;
			TreeMap<String, Integer> mapToList = getWordsMap(input);
			for(Integer v : mapToList.values())
				countOfWords += v;
			for(Map.Entry<String, Integer> entry : mapToList.entrySet())
			{
				String[] toList = new String[3];
				Double toListInt = (entry.getValue() / (double)countOfWords) * 100;
				toList[0] = entry.getKey();
				toList[1] = entry.getValue().toString();
				toList[2] = toListInt.toString();
				listToCSVF.add(toList);
			}
			returnCSVFile.setFileName("result.csv");
			returnCSVFile.setTableOfValues(listToCSVF);
		} catch(IOException ioe) {
			System.out.println("File " + input + " not found");
			ioe.printStackTrace(System.out);
		}
		return returnCSVFile;
	}
	
	/**
	 * Function merge file to words, and create sorted TreeMap&lt;Word,Count&gt;. <br/>
	 *  
	 * @param input file from we gets words. <br/>
	 * @return HashMap with words and its counts.<br/>
	 * 
	 */
	
    private static TreeMap<String, Integer> getWordsMap(String input) throws IOException
    {
        Pattern pattern = Pattern.compile("[^a-z^A-Z^0-9^а-я^А-Я]+");
		HashMap<String, Integer> wordsMap = null;
		try
		{
			wordsMap = new HashMap();
			String fileAsString = readFileAsString(input);
			String[] words = fileAsString.split(pattern.pattern());
			for(String word : words)
			{
				if(wordsMap.containsKey(word))
					wordsMap.put(word, wordsMap.get(word) + 1);
				else
					wordsMap.put(word, 1);
			}
		} catch(IOException ioe) {
			throw ioe;
		}
		MapComparator comparator = new MapComparator(wordsMap);
		TreeMap<String, Integer> returnWordsMap = new TreeMap(comparator);
		returnWordsMap.putAll(wordsMap);
		return returnWordsMap;
    }
	
	/**
	 * Function 
	 * 
	 * @param filePath the way to file
	 * @return file as a String
	 * @throws java.io.IOException 
	 */
	
	private static String readFileAsString(String filePath) throws java.io.IOException
	{
		byte[] buffer = new byte[(int) new File(filePath).length()];
		FileInputStream f = new FileInputStream(filePath);
		f.read(buffer);
		return new String(buffer);
	}
	
	/**
	 * Comparator for sort map; <br/>
	 */
	
	private static class MapComparator implements Comparator
	{
		private Map map;
		
		/**
		 * Constructor for ValueComparator.<br/>
		 * 
		 * @param map 
		 */
		
		public MapComparator(Map map)
		{
			this.map = map;
		}
		
		/**
		 * Implements a compare function; <br/>
		 * 
		 * @param a ,
		 * @param b Objects to compare(Integer)
		 * @return if a &lt; b - "1", else "-1"
		 */
		@Override
		public int compare(Object a, Object b)
		{			
			if((Integer)map.get(a) < (Integer)map.get(b))
				return 1;
			else 
				return -1;
		}
	
	}
}
